﻿namespace SuperMarieApi.App.Controllers.Framework.DataAccess.SqlBuilder
{
    using System.Collections;
    using System.Data;

    public class SqlCondition : Condition
    {
        public SqlRelation Relation { get; private set; }

        public string ColumnName { get; private set; }

        public SqlOperator Operator { get; private set; }

        public string ParameterName { get; private set; }

        public DbType DbType { get; set; }

        public object Value { get; private set; }

        public SqlCondition(SqlRelation relation, string colName, SqlOperator opName, string paramName, DbType dbType, object value)
        {
            this.Relation = relation;
            this.ColumnName = colName;
            this.Operator = opName;
            this.ParameterName = paramName;
            this.DbType = dbType;
            this.Value = value;
        }

        public override string GetPrepend()
        {
            return this.GetRelationString(this.Relation);
        }

        public override string Build2String(DataCommand dbCommand)
        {
            string opString = this.GetOperatorString(this.Operator);
            switch (this.Operator)
            {
                case SqlOperator.Equal:
                case SqlOperator.NotEqual:
                case SqlOperator.MoreThan:
                case SqlOperator.MoreThanOrEqual:
                case SqlOperator.LessThan:
                case SqlOperator.LessThanOrEqual:
                    dbCommand.AddParameter(this.ParameterName, this.DbType, 0, ParameterDirection.Input, this.Value);
                    return string.Format("{0} {1} {2}", this.ColumnName, opString, this.ParameterName);
                case SqlOperator.LeftLike:
                    dbCommand.AddParameter(this.ParameterName, this.DbType, 0, ParameterDirection.Input, this.GetLeftLikeValue(this.Value));
                    return string.Format("{0} {1} {2}", this.ColumnName, opString, this.ParameterName);
                case SqlOperator.RightLike:
                    dbCommand.AddParameter(this.ParameterName, this.DbType, 0, ParameterDirection.Input, this.GetRightLikeValue(this.Value));
                    return string.Format("{0} {1} {2}", this.ColumnName, opString, this.ParameterName);
                case SqlOperator.Like:
                    dbCommand.AddParameter(this.ParameterName, this.DbType, 0, ParameterDirection.Input, this.GetLikeValue(this.Value));
                    return string.Format("{0} {1} {2}", this.ColumnName, opString, this.ParameterName);
                case SqlOperator.In:
                case SqlOperator.NotIn:
                    string paramList = string.Empty;
                    if (this.Value is IEnumerable)
                    {
                        IEnumerable objList = this.Value as IEnumerable;
                        int i = 0;
                        string paramName = string.Empty;
                        foreach (object obj in objList)
                        {
                            paramName = this.ParameterName + i.ToString();
                            paramList += "," + paramName;
                            dbCommand.AddParameter(paramName, this.DbType, 0, ParameterDirection.Input, obj);
                            i++;
                        }
                        if (paramList.Length > 1)
                        {
                            paramList = paramList.Substring(1);
                        }
                    }
                    else if(this.Value != null)
                    {
                        dbCommand.AddParameter(this.ParameterName, this.DbType, 0, ParameterDirection.Input, this.Value);
                        paramList = this.ParameterName;
                        opString = this.GetOperatorString(SqlOperator.Equal);
                    }
                    if (paramList.Length > 0)
                    {
                        return string.Format("{0} {1} ({2})", this.ColumnName, opString, paramList);
                    }
                    return "";
                case SqlOperator.IsNull:
                case SqlOperator.IsNotNull:
                    return string.Format("{0} {1}", this.ColumnName, opString);
                default:
                    return string.Empty;
            }
        }
    }
}
